package com.fourth.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fourth.dto.LoginDto;
import com.fourth.dto.Result;
import com.fourth.dto.UserDTO;
import com.fourth.entity.CodeMsg;
import com.fourth.entity.User;
import com.fourth.service.IUserService;
import com.fourth.util.ValidateEntityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.fourth.util.Constants.LOGIN_USER_KEY;
import static com.fourth.util.Constants.LOGIN_USER_TTL;

/**
 * @author 曹金波
 */
@Controller
public class IndexController {
    @Autowired
    private IUserService userService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    @RequestMapping("toLogin")
    @ResponseBody
    public Result toLogin(HttpServletRequest request) {
        String token = request.getHeader("access-token");
        if (StrUtil.isBlank(token)) {
            return Result.fail("未登录请先登录");
        }
        stringRedisTemplate.expire(LOGIN_USER_KEY + token, 0, TimeUnit.MILLISECONDS);
        return Result.ok();
    }

    /**
     * 进入注册页面
     *
     * @return String
     */
    @RequestMapping("toRegister")
    public String toRegister() {
        return "register";
    }


    /**
     * 切换登录
     */
    @RequestMapping("tocheck")
    public String chIndex() {
        System.out.println("ss");
        return "cklogin";
    }

    /**
     * @param request 请求
     * @param user    用户
     * @param cpacha  验证码
     * @return Result
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public Result login(HttpServletRequest request, User user, String cpacha) {
        //获取验证码
        String validate = (String) request.getSession().getAttribute("admin_login");
        if (user == null) {
            return Result.fail("用户信息不能为空");
        }
        //检查验证码
        if (!cpacha.equalsIgnoreCase(validate)) {
            return Result.fail("该验证码不正确");
        }
        //检查用户名是否存在
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("user_phone", user.getUserPhone());
        User us = userService.getOne(qw);
        if (us == null) {
            return Result.fail("该手机号不存在");
        }
        //检查密码是否正确
        QueryWrapper<User> qw1 = new QueryWrapper<>();
        qw1.eq("user_phone", user.getUserPhone());
        qw1.eq("user_password", user.getUserPassword());
        List<User> userlist = userService.list(qw1);
        if (userlist.size() == 0) {
            return Result.fail("该密码不正确");
        }
        //销毁session中的验证码
        request.getSession().setAttribute("admin_login", null);
        // TODO 保存用户信息到redis
        // TODO 生成token
        String token = UUID.randomUUID().toString();
        // TODO 将User对象转为Hash存储
        final UserDTO userDTO = BeanUtil.copyProperties(us, UserDTO.class);
        final Map<String, Object> map = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((fieldName, filedValue) -> filedValue.toString())
        );

        // TODO 存储对象
        stringRedisTemplate.opsForHash().putAll(LOGIN_USER_KEY + token, map);
        // TODO 设置Token有效期
        stringRedisTemplate.expire(LOGIN_USER_KEY + token, LOGIN_USER_TTL, TimeUnit.MILLISECONDS);
        return Result.ok("登录成功", token);

    }

    /**
     * 用户注册
     *
     * @param request request
     * @param user    用户
     * @return Result
     */
    @RequestMapping(value = "/reg", method = RequestMethod.POST)
    @ResponseBody
    public Result reg(HttpServletRequest request, User user) {
        CodeMsg validated = ValidateEntityUtil.validate(user);
        String msg = validated.getMsg();
        if (validated.getCode() != CodeMsg.SUCCESS.getCode()) {
            return Result.fail(msg);
        }
        //验证身份证号是否合法
        String userIdCard = user.getUserIdCard();
        String regex = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        if (!userIdCard.matches(regex)) {
            return Result.fail("身份证号不合法");
        }
        //验证手机号是否合法
        String userPhone = user.getUserPhone();
        String regex1 = "1[34578][0-9]{9}";
        if (!userPhone.matches(regex1)) {
            return Result.fail("手机号码不合法");
        }
        //验证邮箱是否合法
        String userEmail = user.getUserEmail();
        String regex2 = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
        if (!userEmail.matches(regex2)) {
            return Result.fail("邮箱不合法");
        }
        if (user == null) {
            return Result.fail("用户信息不能为空");
        }
        //检查用户名是否存在
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("user_name", user.getUserName());
        User us = userService.getOne(qw);
        if (us != null) {
            return Result.fail("该用户名已经存在");
        }
        //检查身份证是否存在
        QueryWrapper<User> qw1 = new QueryWrapper<>();
        qw1.eq("user_id_card", user.getUserIdCard());
        List<User> list = userService.list(qw1);
        if (list.size() != 0) {
            return Result.fail("该身份证已经存在");
        }
        //插入数据库中
        boolean save = false;
        try {
            save = userService.save(user);
        } catch (Exception e) {
            return Result.fail("注册失败,");
        }
        return Result.ok("注册成功");
    }


    /**
     * 用户验证码登录
     *
     * @return Result
     */
    @RequestMapping(value = "/loginByCode", method = RequestMethod.POST)
    @ResponseBody
    public Result loginByCode(LoginDto loginDto) {
        String phone = loginDto.getUserPhone();
        String code = loginDto.getCode();

        System.out.println(phone + code + "--------------------");

        if (phone == null) {
            return Result.fail("手机号不能为空");
        }

        //设置redis的key
        String redisKey = phone + ":validCode";
        //获取验证码
        String realCode = (String) stringRedisTemplate.opsForValue().get(redisKey);
        //检查验证码
        if (!code.equalsIgnoreCase(realCode)) {
            return Result.fail("该验证码不正确");
        }

        //检查用户名是否存在
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("user_phone", phone);
        User us = userService.getOne(qw);
        if (us == null) {
            return Result.fail("该用户名不存在");
        }

        //保存用户信息到redis
        //生成token
        String token = UUID.randomUUID().toString();
        //将User对象转为Hash存储
        final UserDTO userDTO = BeanUtil.copyProperties(us, UserDTO.class);
        final Map<String, Object> map = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((fieldName, filedValue) -> filedValue.toString())
        );

        //存储对象
        stringRedisTemplate.opsForHash().putAll(LOGIN_USER_KEY + token, map);
        //设置Token有效期
        stringRedisTemplate.expire(LOGIN_USER_KEY + token, LOGIN_USER_TTL, TimeUnit.MILLISECONDS);
        return Result.ok("登录成功", token);

    }


}
